#!/usr/bin/env perl

#If queries are conducted iteratively, the 'QueryProcessor' and 'SubcomplexMerger' module must conserve the state from
#the last query. Here it is tested that no information is lost and the results are complete. 

use QueryProcessor;
use SubcomplexMerger;
use SubcomplexFinder;
use Scorer;

use Test::More;
use Set::Scalar;
use PDL;
use PDL::Transform;
use File::Basename qw/dirname/;
use File::Spec::Functions;

use strict;
use warnings;

#'inf' not accepted by 'strict'
my $inf = 1000000000;

#get path to test data
my $pathCofm = catdir(dirname(__FILE__), 'testData');
$pathCofm = join '',$pathCofm,'/';

#initialize modules
my $scorer = Scorer->new(maxRMSD=>5, scoreRangeMax=>100);
my $queryProcessor = QueryProcessor->new(scorer=>$scorer, pathCofm=>$pathCofm);

#merging is never interrupted
my @referenceResults = getAllResults($inf);

#mergeOps set other than inf, merging is interrupted
my @results1 = getAllResults(1);
my @results2 = getAllResults(2);
my @results5 = getAllResults(5);
my @results10 = getAllResults(10);
my @results50 = getAllResults(50);

ok(assureSame(\@referenceResults, \@results1),"mergeOps 1");
ok(assureSame(\@referenceResults, \@results2),"mergeOps 2");
ok(assureSame(\@referenceResults, \@results5),"mergeOps 5");
ok(assureSame(\@referenceResults, \@results10),"mergeOps 10");
ok(assureSame(\@referenceResults, \@results50),"mergeOps 50");


#executes the query loop, until Query Processor signals finished
sub getAllResults{
	my($mergeOps)=@_;
	$queryProcessor->reset();
	my @results=();
	my $l=1;
	while($l){
		my ($anotherQueryNeeded, @subcomplexes) = $queryProcessor->query("10gs","20gs",$inf,$mergeOps,$inf);
		push @results, @subcomplexes;
		$l = $anotherQueryNeeded;
	}
	return @results;
}

#assure identity of results over same RMSD value
sub assureSame{
	my ($a, $b)=@_;
	if(scalar(@{$a}) != scalar(@{$b})){
		return 0;
	} else {
		my $detectedSubcomplexes=Set::Scalar->new();
		my $referenceSubcomplexes=Set::Scalar->new();
		for(my $i=0; $i<scalar(@{$a}); $i++){
			$detectedSubcomplexes->insert($b->[$i]->rmsd);
			$referenceSubcomplexes->insert($b->[$i]->rmsd);
		}
		return ($detectedSubcomplexes == $referenceSubcomplexes);
	}
}

done_testing;
